﻿using System;
using System.Collections.Generic;
using Neatly.Hierarchy;
using Neatly.UI;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using Object = UnityEngine.Object;

namespace PandoraEditor.Window
{
    [PdrWindowAbbr("项目检测工具")]
    public class ProjectCheckWindow : NavFuncBase<UnityEngine.Object>
    {
        public ProjectCheckWindow()
        {
            AddNavAction("SpriteName错误", CheckPrefabNImage);
            AddNavAction("Hierarchy导出错误", CheckErrorHierarchy);
            AddNavAction("Hierarchy多个", CheckMultiHierarchy);
            AddNavAction("RawImage检测", CheckPrefabRawImage);
            AddFixAction("修复SpriteName错误", FixePrefabNImage);
        }

        #region Navigation

        private void CheckPrefabRawImage(AssetObject assetObject)
        {
            GameObject go = assetObject.gameObject;
            var images = go.GetComponentsInChildren<RawImage>(true);
            for (int i = 0; i < images.Length; i++)
            {
                RawImage image = images[i];
                m_ResultSet.Add("RawImage错误", "RawImage错误", go);
                LogAppend("RawImage错误", assetObject, image);
            }
        }

        private void CheckPrefabNImage(AssetObject assetObject)
        {
            GameObject go = assetObject.gameObject;
            var images = go.GetComponentsInChildren<NImage>(true);
            foreach (var image in images)
            {
                if (!image.sprite || !image.GetMaterial() || string.IsNullOrEmpty(image.SpriteName) || image.SpriteName != image.sprite.name)
                {
                    m_ResultSet.Add("SpriteName错误", "NImage错误", go);
                    LogAppend("SpriteName错误", assetObject, image);
                }
            }
        }

        private void CheckMultiHierarchy(AssetObject assetObject)
        {
            GameObject go = assetObject.gameObject;
            var hierarchyArray = go.GetComponentsInChildren<NodeHierarchy>();
            if (hierarchyArray.Length>1)
            {
                m_ResultSet.Add("Hierarchy多个", "多个", go);
                foreach (var nodeHierarchy in hierarchyArray)
                {
                    
                    LogAppend("Hierarchy导出错误", go.name, nodeHierarchy.name);
                }
            }
        }

        private void CheckErrorHierarchy(AssetObject assetObject)
        {
            GameObject go = assetObject.gameObject;
            var hierarchy = go.GetComponent<NodeHierarchy>();
            Dictionary<string, string> map = new Dictionary<string, string>();
            if (hierarchy)
            {
                for (var i = 0; i < hierarchy.widgets.Length; i++)
                {
                    var widget = hierarchy.widgets[i];
                    var itemName = widget.name;
                    if (map.ContainsKey(itemName))
                    {
                        m_ResultSet.Add("Hierarchy导出错误", "item名重复", go);
                        LogAppend("Hierarchy导出错误", go.name, itemName);
                    }
                    else
                    {
                        map.Add(itemName, "");
                    }

                    if (widget.item == null)
                    {
                        m_ResultSet.Add("Hierarchy导出错误", "item为null", go);
                        LogAppend("Hierarchy导出错误", go.name, itemName);
                    }
                }

                if (hierarchy.ltrList != null)
                {
                    for (var i = 0; i < hierarchy.ltrList.Length; i++)
                    {
                        var widget = hierarchy.ltrList[i];
                        if (widget == null)
                        {
                            m_ResultSet.Add("Hierarchy导出错误", "ltr list错误", go);
                            LogAppend("Hierarchy导出错误", go.name, "ltr list");
                        }
                    }
                }

                if (hierarchy.externals != null)
                {
                    for (var i = 0; i < hierarchy.externals.Length; i++)
                    {
                        var widget = hierarchy.externals[i];
                        var itemName = widget.name;
                        if (widget.item == null)
                        {
                            m_ResultSet.Add("Hierarchy导出错误", "externals 为null", go);
                            LogAppend("Hierarchy导出错误", go.name, itemName);
                        }
                    }
                }
            }
        }

        private void FixePrefabNImage(AssetObject assetObject)
        {
            GameObject go = assetObject.gameObject;
            var images = go.GetComponentsInChildren<NImage>(true);
            for (int i = 0; i < images.Length; i++)
            {
                NImage image = images[i];
                if (image.sprite == null || image.GetMaterial() == null || string.IsNullOrEmpty(image.SpriteName) ||
                    image.SpriteName != image.sprite.name)
                {
                    GameObject source = go;
                    GameObject newGo = PrefabUtility.InstantiatePrefab(source) as GameObject;
                    if (UIUtility.FixSpriteMiss(newGo))
                    {
                        PrefabUtility.ReplacePrefab(newGo, source, ReplacePrefabOptions.ConnectToPrefab);
                    }

                    Object.DestroyImmediate(newGo);
                }
            }
        }

        bool IncludeRightAtlas(string atlasName, Sprite sprite)
        {
            string[] commonAtlas = new[] {"common", "lobby", "item", "portrait"};
            var spriteName = sprite.texture.name;
            if (spriteName.Contains(atlasName))
            {
                return false;
            }

            for (int i = 0; i < commonAtlas.Length; i++)
            {
                if (spriteName.Contains(commonAtlas[i]))
                {
                    return false;
                }
            }

            return true;
        }

        #endregion

        private void AddNavAction(string title, params Action<AssetObject>[] handlers)
        {
            AddNavButton(title, () =>
            {
                Clear();
                string str = "Check All Prefabs";
                PdrWindowHelper.CheckUIPrefabs(str, handlers);
                WriteLog();
            });
        }

        private void AddFixAction(string title, params Action<AssetObject>[] handlers)
        {
            AddFixButton(title, () =>
            {
                Clear();
                string str = "fix All Prefabs";
                PdrWindowHelper.CheckUIPrefabs(str, handlers);
                WriteLog();
            });
        }
    }
}